<?php

declare(strict_types=1);

namespace app\controller\system;

use app\BaseController;
use app\model\Region;
use app\model\User;
use app\service\factory\ResponseFactory;
use app\service\org\OrgQuickCreateService;
use app\service\org\OrgAuditService;
use app\service\user\CompanyVerificationService;
use app\service\user\IndividualVerificationService;
use app\validate\org\OrgAuditValidate;
use app\validate\org\OrgAuditQuickCreateValidate;
use InvalidArgumentException;
use think\Response;
use Throwable;

class OrgAudit extends BaseController
{
    public function index(OrgAuditService $auditService): Response
    {
        try {
            $page = max(1, (int) $this->request->param('page', 1));
            $pageSize = (int) $this->request->param('page_size', 20);
            $pageSize = $pageSize > 0 ? min($pageSize, 100) : 20;

            $filters = $this->request->only([
                'keyword',
                'org_type',
                'status',
                'region_id',
            ], 'get');

            $context = $this->buildOperatorContext();

            $result = $auditService->paginate($filters, $page, $pageSize, $context);

            return json(ResponseFactory::paginated(
                $result['list'],
                (int) $result['total'],
                $page,
                $pageSize
            ));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function fastCreate(OrgQuickCreateService $quickCreateService): Response
    {
        try {
            $operatorId = (int) ($this->request->user_id ?? 0);
            if ($operatorId <= 0) {
                return json(ResponseFactory::error('未登录或缺少用户信息', 401));
            }

            $payload = $this->request->post();

            $this->validate($payload, OrgAuditQuickCreateValidate::class . '.create');

            $result = $quickCreateService->create($payload, $operatorId);

            return json(ResponseFactory::success($result, '组织已创建并审核通过'));
        } catch (InvalidArgumentException $e) {
            return json(ResponseFactory::error($e->getMessage(), 422));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function approve(
        int $userId,
        CompanyVerificationService $companyVerificationService,
        IndividualVerificationService $individualVerificationService
    ): Response
    {
        try {
            $payload = $this->request->post();
            $payload['id'] = $userId;

            $this->validate($payload, OrgAuditValidate::class . '.approve');

            $type = (string) ($payload['type'] ?? '');
            if (!in_array($type, ['company', 'individual'], true)) {
                return json(ResponseFactory::error('缺少或不支持的认证类型', 422));
            }

            $operatorId = (int) ($this->request->user_id ?? 0);
            if ($operatorId <= 0) {
                return json(ResponseFactory::error('未登录或缺少用户信息', 401));
            }

            $options = ['approved_by' => $operatorId];
            if (isset($payload['region_id']) && $payload['region_id'] !== '') {
                $options['region_id'] = (int) $payload['region_id'];
            }

            if ($type === 'company') {
                $companyVerificationService->approveCompany($userId, $options);
            } else {
                $individualVerificationService->approveIndividual($userId, $options);
            }

            return json(ResponseFactory::success([
                'user_id' => $userId,
                'type' => $type,
            ], '已审核通过'));
        } catch (InvalidArgumentException $e) {
            return json(ResponseFactory::error($e->getMessage(), 422));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function reject(
        int $userId,
        CompanyVerificationService $companyVerificationService,
        IndividualVerificationService $individualVerificationService
    ): Response
    {
        try {
            $payload = $this->request->post();
            $payload['id'] = $userId;

            $this->validate($payload, OrgAuditValidate::class . '.reject');

            $type = (string) ($payload['type'] ?? '');
            if (!in_array($type, ['company', 'individual'], true)) {
                return json(ResponseFactory::error('缺少或不支持的认证类型', 422));
            }

            $remark = (string) ($payload['remark'] ?? '');

            if ($type === 'company') {
                $companyVerificationService->rejectCompany($userId, $remark);
            } else {
                $individualVerificationService->rejectIndividual($userId, $remark);
            }

            return json(ResponseFactory::success([
                'user_id' => $userId,
                'type' => $type,
            ], '已驳回'));
        } catch (InvalidArgumentException $e) {
            return json(ResponseFactory::error($e->getMessage(), 422));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    /**
     * 组装当前操作员的角色、身份与区域上下文
     */
    private function buildOperatorContext(): array
    {
        $operatorId = (int) ($this->request->user_id ?? 0);
        if ($operatorId <= 0) {
            return [];
        }

        /** @var User|null $operator */
        $operator = User::with([
            'roles',
            'identities' => static function ($query) {
                $query->whereNull('delete_time');
            },
            'regionUsers' => static function ($query) {
                $query->whereNull('delete_time');
            },
            'regionUsers.region',
        ])->find($operatorId);

        if (!$operator) {
            return [];
        }

        $roleSlugs = [];
        foreach ($operator->roles as $role) {
            $slug = (string) ($role->slug ?? '');
            if ($slug !== '') {
                $roleSlugs[] = $slug;
            }
        }

        $identities = [];
        $identityRegionIds = [];
        foreach ($operator->identities as $identity) {
            $item = [
                'type' => strtolower((string) ($identity->identity_type ?? '')),
                'status' => (int) ($identity->status ?? 0),
                'region_id' => $identity->region_id ? (int) $identity->region_id : null,
            ];
            $identities[] = $item;

            if ($item['region_id'] !== null) {
                $identityRegionIds[] = $item['region_id'];
            }
        }

        $regionIds = [];
        $regionPaths = [];
        foreach ($operator->regionUsers as $relation) {
            if ((int) ($relation->status ?? 1) !== 1) {
                continue;
            }
            $regionId = $relation->region_id ? (int) $relation->region_id : null;
            if (!$regionId) {
                continue;
            }
            $regionIds[] = $regionId;
            $region = $relation->region;
            if ($region) {
                $regionPaths[$regionId] = (string) ($region->path ?? '');
            }
        }

        $allRegionIds = array_values(array_unique(array_merge($regionIds, $identityRegionIds)));

        if ($allRegionIds !== []) {
            $paths = Region::whereIn('id', $allRegionIds)->column('path', 'id');
            foreach ($paths as $id => $path) {
                $regionPaths[(int) $id] = (string) $path;
            }
        }

        return [
            'operator_id' => $operatorId,
            'role_slugs' => array_values(array_unique($roleSlugs)),
            'identities' => $identities,
            'region_scope' => [
                'ids' => $allRegionIds,
                'paths' => $regionPaths,
            ],
        ];
    }

}
